#ifndef IMAGE_INFO_H
#define IMAGE_INFO_H

#include <stddef.h>

/** Wrapper class for CImg images.
 *
 *  Purpose of the class is to wrap up all CImg specific code so that the
 *  massive CImg template header file need to be compiled only once in this
 *  module and then the compiled module can be just linked. This speeds up
 *  compilation during development a great deal.
 *
 *  Note that CImg saves image data in format "R1R2R3R4R5R6 ... G1G2G3G4G5G6".
 */
class image
{
private:
	void* cimg;
public:
	image(): cimg(0) {}
	~image();

	/**
	 * Create (on separate image, for now) canny edge detection from the
	 * loaded image.
	 *
	 * (http://en.wikipedia.org/wiki/Canny_edge_detector)
	 *
	 * TODO: clean code, document.
	 */
	void canny_edge_detection(float alpha);

	/**
	 * Displays the (loaded) image on screen.
	 *
	 * Function creates a window that displays the image. Program sits in
	 * a loop waiting for key to be pressed. After a key press the window
	 * is closed and function returns.
	 */
	void display();

	/**
	 * Compute the histogram-equalized version of the image instance.
	 *
	 * @param	nb_levels Number of histogram levels used for the
	 *       	          equalization.
	 * @param	value_min Minimum pixel value considered for the
	 *       	          histogram computation. All pixel values
	 *       	          lower than value_min will not be counted.
	 * @param	value_max Maximum pixel value considered for the
	 *       	          histogram computation. All pixel values
	 *       	          higher than value_max will not be counted.
	 * @note	If value_min==value_max==0 (default behavior), the
	 *      	function first estimates the whole range of pixel
	 *      	values then uses it to equalize the histogram.
	 */
	void equalize(const unsigned int nb_levels, const char value_min = 0,
	              const char value_max = 0);

	unsigned char* getData(); /**< Getter for image's pixel data. */
	size_t getDepth(); /**< Getter for image's color depth. */
	size_t getHeight(); /**< Getter for image's height. */
	size_t getSpectrum(); /**< Getter for image's spectrum (0). */
	size_t getWidth(); /**< Getter for image's width. */

	/**
	 * Load image data from file into internal buffer.
	 *
	 * Function reserves memory for new image, loads it from disk and
	 * sets its parameters for quick lookup.
	 *
	 * @param	filename Relative path to the file to be loaded.
	 */
	void load(const char *filename);

	/**
	 * Normalize multi-valued pixels of the image instance, with respect
	 * to their L2-norm.
	 */
	void normalize();

	/**
	 * Uniformly quantize values of the image instance into N levels.
	 *
	 * @param	nb_levels Number of quantization levels.
	 * @param	keep_range Tells if resulting values keep the same
	 *       	           range as the original ones.
	 */
	void quantize(const unsigned int nb_levels,
	              const bool keep_range = true);

	/**
	 * Sharpen image using anisotropic shock filters or inverse diffusion.
	 */
	void sharpen(const float amplitude, const bool sharpen_type = false,
		     const float edge = 1, const float alpha = 0,
	             const float sigma = 0);

	void toGrayscale(); /**< Make image single channeled (grayscaled). */
};

#endif
